﻿

using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;

namespace PluginDB
{
    internal interface IEntityRepository
    {
        
    }

    public class MoviesRepository : IEntityRepository
    {
        private readonly Repository<Video, PluginDbEntities> _videoRepository;
        private readonly Repository<VideosLink, PluginDbEntities> _videosLinkRepository;
        private readonly CommonRepository _commonRepository;

        public MoviesRepository(PluginDbEntities pluginDbEntities)
        {
            _videoRepository = new Repository<Video, PluginDbEntities>(pluginDbEntities);
            _videosLinkRepository = new Repository<VideosLink, PluginDbEntities>(pluginDbEntities);
            _commonRepository = new CommonRepository(pluginDbEntities);
        }

        internal bool IsMovieExists(string pluginUrl)
        {
            return _videoRepository.DoQuery(
                new Specification<Video>(v => v.PluginUrl.ToLower() == pluginUrl.ToLower())).Any();
        }

        #region Get Methods
        internal List<Video> GetMoviesByCategoryId(long categoryId)
        {
            var videos =
                _videoRepository.DoQuery().Where(v => (v.Categories.Where(c => c.CategoryID == categoryId)).Count() > 0);
            return videos.ToList();
        }

        internal List<Video> GetAllVideos()
        {
            return _videoRepository.SelectAll().OrderByDescending(video => video.VideoID).ToList();
        }

        internal List<Video> GetHebDubVideos()
        {
            return _videoRepository.DoQuery(
                new Specification<Video>(v => v.Is_Heb_Dub)).OrderByDescending(video => video.VideoID).ToList();
        }

        internal List<Video> GetHebSubVideos()
        {
            return _videoRepository.DoQuery(
                new Specification<Video>(v => v.Is_Heb_Sub)).OrderByDescending(video => video.VideoID).ToList();
        }

        internal List<Video> GetLatestVideosList()
        {
            var videos = _videoRepository.SelectAll().OrderByDescending(a => a.VideoID);
            return videos.ToList();
        } 
        #endregion

        internal void AddMovie(PluginVideoInfo pluginVideoInfo)
        {
            try
            {
                var video = new Video
                {
                    VideoID = pluginVideoInfo.VideoID,
                    VideoName = pluginVideoInfo.VideoName,
                    EnglishVideoName = pluginVideoInfo.EnglishVideoName,
                    HebrewVideoName = pluginVideoInfo.HebrewVideoName,
                    ImageUrl = pluginVideoInfo.ImageUrl,
                    PluginUrl = pluginVideoInfo.PluginUrl,
                    Plot = pluginVideoInfo.Plot,
                    Site = _commonRepository.GetSite(pluginVideoInfo.SiteName),
                };

                foreach (var link in pluginVideoInfo.Links)
                {
                    if (link.IsBrokenLink) continue;

                    video.VideosLinks.Add(new VideosLink
                    {
                        LinkURL = link.LinkURL,
                        Source = _commonRepository.GetSource(link.SourceName)
                    });
                }

                //TODO: add rule to extract category name
                foreach (var category in pluginVideoInfo.Categories)
                {
                    video.Categories.Add(_commonRepository.GetCategory(category));
                }


                //If there is no VALID link in video then dont save it
                if (video.VideosLinks.Count == 0)
                {
                    Debug.WriteLine(string.Format("Video:{0} has no valid links. abort saving it.", video.VideoName));
                    return;
                }

                _videoRepository.Add(video);
                _videoRepository.Save();
            }
            catch (UpdateException ex)
            {
                Console.WriteLine("UpdateException durin update. Ex={0}", ex.InnerException.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception durin Save. Ex={0}", ex.InnerException.Message);
            }
        }

        internal List<Video> GetAtoZMoviesList(string startWord)
        {
            var videos = _videoRepository.SelectAll().OrderBy(videoName => videoName.VideoName).ToList();
            return videos.Where(v => v.VideoName.StartsWith(startWord)).ToList();
        }

        internal List<Video> GetMoviesBySite(long siteId)
        {
            var videos = _videoRepository.DoQuery(
                new Specification<Video>(a => a.Site.SiteID == siteId));
            return videos.ToList();
        }

        internal Video GetMovieByID(long videoId)
        {
            var video = _videoRepository.DoQuery(
                new Specification<Video>(v => v.VideoID == videoId)).Include("VideosLinks").FirstOrDefault();
            return video;
        }

        internal VideosLink GetVideoLinkByID(long linkId)
        {
            var link = _videosLinkRepository.DoQuery(
                new Specification<VideosLink>(v => v.LinkID == linkId)).FirstOrDefault();
            return link;
        }

        internal List<Video> GetMoviesBySearchText(string searchText)
        {
            var videos = _videoRepository.Session.Videos.Include("VideosLinks").Where(
                v => v.VideoName.ToLower().Contains(searchText.ToLower()));
            return videos.OrderBy(videoName => videoName.VideoName).ToList();
        }
    }
}
